package com.bckj.fastboot.core.util;

import com.bckj.fastboot.core.jackson.JsonUtils;
import com.bckj.fastboot.core.lang.func.IGetter;
import com.bckj.fastboot.core.lang.model.Result;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Map;
import java.util.Objects;

public record EntityMapWrapper<T> (Map<String, Object> map, Class<T> tClass) implements MapOp {

    public EntityMapWrapper {
        Objects.requireNonNull(map);
    }

    @Override
    public Object get(String key) {
        return map.get(key);
    }

    @SuppressWarnings("unchecked")
    public <R> R getValue(IGetter<T> getter) {
        String fieldName = LambdaUtils.getSerializedLambda(getter).getFieldName();
        return (R) map.get(fieldName);
    }

    public String getString(IGetter<T> getter) {
        return getString(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public Long getLong(IGetter<T> getter) {
        return getLong(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public Integer getInteger(IGetter<T> getter) {
        return getInteger(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public Float getFloat(IGetter<T> getter) {
        return getFloat(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public Double getDouble(IGetter<T> getter) {
        return getDouble(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public Boolean getBoolean(IGetter<T> getter) {
        return getBoolean(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public LocalDateTime getLocalDateTime(IGetter<T> getter) {
        return getLocalDateTime(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public LocalDate getLocalDate(IGetter<T> getter) {
        return getLocalDate(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public LocalTime getLocalTime(IGetter<T> getter) {
        return getLocalTime(LambdaUtils.getSerializedLambda(getter).getFieldName());
    }

    public Result<T> toEntity() {
        return SafeOps.runCatching(() -> JsonUtils.convertValue(map, tClass));
    }
}
